package com.foreveross.service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.foreveross.action.DDManagerContraller;
import com.foreveross.common.CommonUtil;
import com.foreveross.common.Constants;
import com.foreveross.common.Exception.ExceptionConstant;
import com.foreveross.dao.PayCostFavorableInfoDAO;
import com.foreveross.util.DateUtil;
import com.foreveross.vo.HrCode;
import com.foreveross.vo.OrderInfo;
import com.foreveross.vo.PayCostFavorableInfo;
import com.foreveross.vo.common.ResultVo;
import com.foreveross.weixin.service.PayRefundService;
import com.foreveross.weixin.service.PayUnifiedOrderService;
import com.foreveross.weixin.util.WeixinUtil;
import com.foreveross.weixin.vo.pay.PayOrderQueryResult;
import com.foreveross.weixin.vo.pay.PayRefundResult;
import com.foreveross.weixin.vo.pay.PayRequestVo;

@Service("payCostFavorableInfoService")
@Transactional
public class PayCostFavorableInfoService extends BaseService {
	
	private Logger log = Logger.getLogger(PayCostFavorableInfoService.class);
	
	@Resource
	private OrderInfoService orderInfoService;
	@Resource
	private DDManagerService ddManagerService;
	@Resource
	private PayCostFavorableInfoDAO payCostFavorableInfoDAO;
	@Resource
	private HrFavorableService hrFavorableService;

	
	public ResultVo payCostFavorableInfo(String body,String total_fee,
			String notify_url,String addrIp,String weixinId,
			String appId,String mchId,String apiKey,String orderIds)  throws Exception{
		return sendPay(body, total_fee, notify_url, addrIp, weixinId, appId, mchId,apiKey, orderIds);
	}
	
	private ResultVo sendPay(String body,String total_fee,
			String notify_url,String addrIp,String weixinId,
			String appId,String mchId,String apiKey,String orderIds) throws Exception{
		ResultVo resultVo = new ResultVo();
		if(validatePayOrder(total_fee, orderIds)){
			PayRequestVo payRequestVo = PayUnifiedOrderService.sendPay(body, total_fee, 
					addrIp, weixinId, notify_url,appId,mchId,apiKey);
			resultVo.setSuccess(true);
			resultVo.setData(payRequestVo);
		}else{
			resultVo.setSuccess(false);
			resultVo.setMessage(ExceptionConstant.getExceptionMessage(ExceptionConstant.PAY_TOTAL_INCONFORMITY));
		}
		return resultVo;
	}
	
	
	private boolean validatePayOrder(String total_fee,String orderIds){
		boolean validateResult = false;
		try{
			if(total_fee !=null && !"".equals(total_fee) && 
					orderIds !=null && !"".equals(orderIds)){
				double orderCost = getCost(orderIds);
				int cost = new BigDecimal(Double.toString(orderCost)).multiply(new BigDecimal("100")).intValue();
				if (Integer.parseInt(total_fee) == cost) validateResult = true;
				else  validateResult = false;
			}
		}catch(Exception e){
			validateResult = false;
		}
		
		return validateResult;
	}
	
	private double getCost(String orderIds) throws Exception{
		double orderCost = 0;
		for(String orderId : orderIds.split(",")){
			OrderInfo orderInfo = orderInfoService.getOrderInfoById(orderId);
			orderCost += orderInfo.getCount()*orderInfo.getHrFavorable().getFavorablePrice();
		}
		return orderCost;
	}
	
	public List<OrderInfo> offLineOrderInfoCallBack(String orderIds,int payStatus)  throws Exception{
		return updatePayCostFavorableInfo(orderIds, payStatus);
	}
	
	private List<OrderInfo> updatePayCostFavorableInfo(String orderIds,int payStatus)  throws Exception {
		List<OrderInfo> orderInfoList = new ArrayList<OrderInfo>();
		for(String orderId : orderIds.split(",")){
			List<PayCostFavorableInfo> payCostFavorableInfoList =  payCostFavorableInfoDAO.findPayCostFavorableInfoList(null, orderId, null, null, null, null,
					null, null, null, null, null);
			for(PayCostFavorableInfo payCostFavorableInfo : payCostFavorableInfoList){
				payCostFavorableInfo.setPayStatus(payStatus);
				payCostFavorableInfoDAO.updateObject(payCostFavorableInfo);
				
				OrderInfo orderInfo = payCostFavorableInfo.getOrderInfo();
				orderInfo.setPayStatus(payStatus);
				orderInfoService.updateObject(orderInfo);
				
				orderInfoList.add(orderInfo);
			}
		}
		
		return orderInfoList;
	}


	private boolean savePayCostFavorableInfo(String orderIds,int payStatus,Date chargeTime,
			String payType,String outTradeNo){
		boolean isTrue = false;
		try{
			List<OrderInfo> orderInfoList = orderInfoService.updateOrderInfo(orderIds, payStatus, chargeTime, payType, outTradeNo);
			if(orderInfoList!=null && orderInfoList.size()>0){
				for(OrderInfo orderInfo : orderInfoList){
					PayCostFavorableInfo payCostFavorableInfo = new PayCostFavorableInfo();
					payCostFavorableInfo.setOrderInfo(orderInfo);
					payCostFavorableInfo.setChargeTime(orderInfo.getChargeTime());
					payCostFavorableInfo.setCost(orderInfo.getHrFavorable().getFavorablePrice()*orderInfo.getCount());
					payCostFavorableInfo.setCount(orderInfo.getCount());
					payCostFavorableInfo.setHouseUser(orderInfo.getHouseUser());
					payCostFavorableInfo.setHrBusiness(orderInfo.getHrBusiness());
					payCostFavorableInfo.setHrFavorable(orderInfo.getHrFavorable());
					payCostFavorableInfo.setHrHouses(orderInfo.getHrHouses());
					payCostFavorableInfo.setOutTradeNo(orderInfo.getOutTradeNo());
					payCostFavorableInfo.setPayStatus(orderInfo.getPayStatus());
					payCostFavorableInfo.setTenement(orderInfo.getTenement());
					payCostFavorableInfo.setPayType(orderInfo.getPayType());
					
					save(payCostFavorableInfo);
					
					hrFavorableService.setCountForHrFavorable(orderInfo.getHrFavorable().getId());
				}
				isTrue = true;
			}else isTrue = false;
			
		}catch(Exception e){
			isTrue = false;
			e.printStackTrace();
		}

		return isTrue;
	}

	public boolean payCostFavorableInfoCallback(String orderIds, String nonceStr,
		    String appId, String mchId, String apiKey,String outTradeNo,
			String payType) throws Exception{
		return payCostFavorableInfoCallbackDeal(orderIds, nonceStr, appId, mchId,apiKey, outTradeNo, payType);
	}
	
	private boolean payCostFavorableInfoCallbackDeal(String orderIds, String nonceStr,
			 String appId, String mchId,String apiKey, String outTradeNo,
			String payType)  throws Exception{
		boolean isTrue = false;
		if(payType!=null && payType.equals(String.valueOf(Constants.PAY_TYPE_ONLINE))){
			PayOrderQueryResult payOrderQueryResult = getPayOrderQueryResult(nonceStr, appId, mchId,apiKey, outTradeNo);
			if("SUCCESS".equalsIgnoreCase(payOrderQueryResult.getResult_code())
					&& "SUCCESS".equalsIgnoreCase(payOrderQueryResult.getTrade_state())){
				boolean saveStatus = savePayCostFavorableInfo(orderIds, Constants.PAY_STATUS_SUCCESS, DateUtil.StringToDate(payOrderQueryResult.getTime_end(), "yyyyMMddHHmmss"), payType, outTradeNo);
				if(saveStatus){
					isTrue = true;
				}else{
					savePayCostFavorableInfo(orderIds, Constants.PAY_STATUS_SYS_FAIL, DateUtil.StringToDate(payOrderQueryResult.getTime_end(), "yyyyMMddHHmmss"), payType, outTradeNo);
					log.error("润优惠微信支付成功，但数据库录入错误!订单号为："+orderIds);
					isTrue = true;
				}
				
			}else{
				savePayCostFavorableInfo(orderIds, Constants.PAY_STATUS_FAIL,DateUtil.StringToDate(payOrderQueryResult.getTime_end(), "yyyyMMddHHmmss"), payType, outTradeNo);
				isTrue = false;
			}
		}else{
			//orderInfoService.updateOrderInfo(orderIds, Constants.PAY_STATUS_FAIL,null, payType, outTradeNo);
			savePayCostFavorableInfo(orderIds, Constants.PAY_STATUS_FAIL,null, payType, outTradeNo);
			isTrue = true;
		}
		
		return isTrue;
	}
	
	/**
	 * 从微信那儿查询订单
	 * @param nonceStr
	 * @param sign
	 * @param appId
	 * @param mchId
	 * @param outTradeNo
	 * @return
	 * @throws Exception
	 */
	private PayOrderQueryResult getPayOrderQueryResult(String nonceStr,
			String appId,String mchId,String apiKey,String outTradeNo) throws Exception{
		PayOrderQueryResult payOrderQueryResult = PayUnifiedOrderService.getPayOrderQueryResult(nonceStr, appId, mchId, apiKey, outTradeNo);
	
		return payOrderQueryResult;
	}
	
	public List<PayCostFavorableInfo> getPayCostFavorableInfoByOrderId(String orderId)  throws Exception{
		return payCostFavorableInfoDAO.findPayCostFavorableInfoList(null, orderId, null, null, null, null,
				null, null, null, null, null);
	}
	
}
